package com.ezops.poc.parser;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.ezops.poc.bo.DefaultBaseDynamicModel;
import com.ezops.poc.util.LoggerUtil;
import com.ezops.poc.util.ParseException;

/**
 * Parse the OrchesTrade response for the trade file sent to OT earlier.
 * 
 * <p>
 * NOTE - Repeating the same logical structure as of ClientFormat Parse
 * ---Violation of DRY----Should extract an interface or use template pattern
 * for this king of parser
 * 
 * @author vgaurav
 * 
 */
@Component(value = "otResponseParser")
public class OTResponseParser implements Processor {

	Logger logger = LoggerFactory.getLogger(OTResponseParser.class);

	/**
	 * The Response will be in following format
	 * EzOpsId,ClientId,OrchestradeId,ErrorMessage,status Create a Reponse
	 * object for each record and send it further down the pipe. NOTE - Single
	 * update should work or probably bulk update will be better then saving
	 * individual response.
	 */
	@Override
	public void process(Exchange exchange) throws Exception {
		logger.trace("Parsing OT response Starts");

		@SuppressWarnings({ "unchecked", "unused" })
		List<List<String>> body = (List<List<String>>) exchange.getIn()
				.getBody();

		logger.trace("-----Response received from OT---------");
		logger.trace(LoggerUtil.getLoggableFormat(body));

		String[] header = extractHeader(body);
		List<List<String>> data = extractData(body);

		try {
			// Set the parsed list of model into exchange body for further
			// processing.
			exchange.getIn().setBody(parse(header, data));
		} catch (Exception e) {
			e.printStackTrace();
			throw new ParseException(e,
					"Error while parsing OT response. Reason - "
							+ e.getMessage());
		}

	}

	private Object parse(String[] header, List<List<String>> data) {

		List<DefaultBaseDynamicModel> convertedList = new ArrayList<DefaultBaseDynamicModel>();

		for (List<String> row : data) {
			DefaultBaseDynamicModel instance = new DefaultBaseDynamicModel();

			Iterator<String> dataIterator = row.iterator();

			// transform row into pojo.
			for (String field : header) {

				instance.addField(field, dataIterator.next());

			}
			convertedList.add(instance);
		}
		return convertedList;
	}

	private List<List<String>> extractData(List<List<String>> body) {

		if (body == null || body.isEmpty()) {
			throw new IllegalArgumentException("Response is empty");
		}
		// remove header
		body.remove(0);
		return body;

	}

	private boolean validateHeaders(List<String> headers) {
		if (headers.isEmpty())
			return false;
		return true;

	}

	private String[] extractHeader(List<List<String>> body) {

		if (body == null || body.size() == 0) {
			throw new IllegalArgumentException(
					"Header in OT response can not be empty");
		}
		List<String> headers = body.get(0);
		validateHeaders(headers);
		return headers.toArray(new String[headers.size()]);

	}

}
